package demo.java.time;

import java.time.*;
import java.util.Date;

/**
 * 时间转换工具类
 * <h2>核心转换原理：</h2>
 * <li>所有转换都以 Instant（UTC 时间戳）作为中间桥梁
 * <li>时区转换主要依赖 ZoneId（如 Asia/Shanghai）和 ZoneOffset（如 +08:00）
 *
 * <h2>关键注意点：</h2>
 * <li>LocalDateTime 不含时区信息，转换为其他类型时需要指定时区
 * <li>工具类中默认使用东八区（Asia/Shanghai），可根据需求修改 DEFAULT_ZONE_ID
 * <li>所有方法都处理了 null 值，避免空指针异常
 *

 */
public class DateTimeConverter {



    // 默认时区（东八区），可根据实际需求修改
    private static final ZoneId DEFAULT_ZONE_ID = ZoneId.of("Asia/Shanghai");

    // ==================== Date ←→ OffsetDateTime ====================

    /**
     * Date 转换为 OffsetDateTime
     * 使用默认时区（东八区）
     */
    public static OffsetDateTime dateToOffsetDateTime(Date date) {
        if (date == null) {
            return null;
        }
        // Date -> Instant -> OffsetDateTime（默认时区偏移）
        return date.toInstant().atZone(DEFAULT_ZONE_ID).toOffsetDateTime();
    }

    /**
     * Date 转换为 OffsetDateTime
     * 指定时区偏移
     */
    public static OffsetDateTime dateToOffsetDateTime(Date date, ZoneOffset offset) {
        if (date == null || offset == null) {
            return null;
        }
        // Date -> Instant -> OffsetDateTime（指定偏移）
        return date.toInstant().atOffset(offset);
    }

    /**
     * OffsetDateTime 转换为 Date
     */
    public static Date offsetDateTimeToDate(OffsetDateTime offsetDateTime) {
        if (offsetDateTime == null) {
            return null;
        }
        // OffsetDateTime -> Instant -> Date
        return Date.from(offsetDateTime.toInstant());
    }

    // ==================== Date ←→ LocalDateTime ====================

    /**
     * Date 转换为 LocalDateTime
     * 使用默认时区（东八区）
     */
    public static LocalDateTime dateToLocalDateTime(Date date) {
        if (date == null) {
            return null;
        }
        // Date -> Instant -> LocalDateTime（默认时区）
        return date.toInstant().atZone(DEFAULT_ZONE_ID).toLocalDateTime();
    }

    /**
     * Date 转换为 LocalDateTime
     * 指定时区
     */
    public static LocalDateTime dateToLocalDateTime(Date date, ZoneId zoneId) {
        if (date == null || zoneId == null) {
            return null;
        }
        // Date -> Instant -> LocalDateTime（指定时区）
        return date.toInstant().atZone(zoneId).toLocalDateTime();
    }

    /**
     * LocalDateTime 转换为 Date
     * 使用默认时区（东八区）
     */
    public static Date localDateTimeToDate(LocalDateTime localDateTime) {
        if (localDateTime == null) {
            return null;
        }
        // LocalDateTime -> Instant（默认时区）-> Date
        return Date.from(localDateTime.atZone(DEFAULT_ZONE_ID).toInstant());
    }

    /**
     * LocalDateTime 转换为 Date
     * 指定时区
     */
    public static Date localDateTimeToDate(LocalDateTime localDateTime, ZoneId zoneId) {
        if (localDateTime == null || zoneId == null) {
            return null;
        }
        // LocalDateTime -> Instant（指定时区）-> Date
        return Date.from(localDateTime.atZone(zoneId).toInstant());
    }

    // ==================== LocalDateTime ←→ OffsetDateTime ====================

    /**
     * LocalDateTime 转换为 OffsetDateTime
     * 使用默认时区偏移（东八区）
     */
    public static OffsetDateTime localDateTimeToOffsetDateTime(LocalDateTime localDateTime) {
        if (localDateTime == null) {
            return null;
        }
        // LocalDateTime + 默认时区偏移 -> OffsetDateTime
        ZoneOffset shanghaiOffsetNow = DEFAULT_ZONE_ID.getRules().getOffset(Instant.now());
        return localDateTime.atOffset(shanghaiOffsetNow);
    }

    /**
     * LocalDateTime 转换为 OffsetDateTime
     * 指定时区偏移
     */
    public static OffsetDateTime localDateTimeToOffsetDateTime(LocalDateTime localDateTime, ZoneOffset offset) {
        if (localDateTime == null || offset == null) {
            return null;
        }
        // LocalDateTime + 指定偏移 -> OffsetDateTime
        return localDateTime.atOffset(offset);
    }

    /**
     * OffsetDateTime 转换为 LocalDateTime
     * 直接剥离时区偏移信息
     */
    public static LocalDateTime offsetDateTimeToLocalDateTime(OffsetDateTime offsetDateTime) {
        if (offsetDateTime == null) {
            return null;
        }
        // 直接获取本地日期时间部分（忽略偏移）
        return offsetDateTime.toLocalDateTime();
    }
}
